﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using BusinessRule.Common;
using BusinessRule.Business;
using BusinessRule.DTO;
using DatabaseAccess.DBUtility;
using System.Threading.Tasks;
using System.Configuration;

//Description:热表转工接收定时任务处理类
//Copyright (c) : 通力凯顿（北京）系统集成有限公司
//Writer:zhangrj
//create Date:2024-09-24
//Rewriter:
//Rewrite Date:

namespace MESScheduledTask
{
    public class RbApsShipReceiveTask
    {
        private ApsPlanConfirmBusiness apsPlanConfirmBusiness = new ApsPlanConfirmBusiness();
        private RbContainerBusiness rbBusiness = new RbContainerBusiness();
        public static readonly int maxParallelSync = Convert.ToInt32(ConfigurationManager.AppSettings["maxParallelSync"].ToString());//最大并行任务数

        private string serverAPIUserName = ConfigurationManager.AppSettings["ServerAPIUserName"].ToString();//camstarAPI用户名
        private string serverAPIPassword = ConfigurationManager.AppSettings["ServerAPIPassword"].ToString();//camstarAPI密码

        /// <summary>
        /// 执行任务
        /// </summary>
        /// <param name="taskList"></param>
        public void RunTaskSync(List<string> taskList)
        {
            //获取需要启动的任务
            DataTable dt = CommonHelper.GetNeedExecuteTask(CommonHelper.TaskTypeEnum.转工计划接收_工步);
            List<Task> tl = new List<Task>();
            foreach (DataRow dr2 in dt.Rows)
            {//开始循环定时任务
                var tempDt = dt.Clone();
                tempDt.ImportRow(dr2);
                var dr = tempDt.Rows[0];//此处必须要给局部变量赋值

                if (taskList.Count >= maxParallelSync)
                {
                    LogHelp.WriteLog("当前正在执行的任务数为：" + taskList.Count.ToString() + " 已达到最大并行限制----------------------------------------------------------------------");
                    break;
                }
                if (taskList.Contains(dr["scheduledtaskid"].ToString()))//已在任务中
                    continue;

                taskList.Add(dr["scheduledtaskid"].ToString());//添加到list中

                tl.Add(Task.Factory.StartNew(() =>
                {
                    try
                    {
                        DealRbShipReceiveTask(dr);
                    }
                    catch (Exception ex)
                    {
                        LogHelp.WriteError(dr["taskname"].ToString() + "定时计算异常", ex);
                        CommonHelper.WriteTaskLog(dr["ScheduledTaskId"].ToString(), "3", ex.Message + ex.StackTrace, "1");
                        return;
                    }
                    finally
                    {
                        LogHelp.WriteLog("任务：" + dr["taskname"].ToString() + " " + dr["taskdesc"].ToString() + " 执行完毕，移除队列");
                        taskList.Remove(dr["scheduledtaskid"].ToString());
                    }
                }, TaskCreationOptions.LongRunning));

            }
            //本次产生的task，需要等待完毕
            Task.WaitAll(tl.ToArray());
        }

        /// <summary>
        /// 处理单个任务
        /// </summary>
        /// <param name="dr"></param>
        public void DealRbShipReceiveTask(DataRow dr)
        {
            if (dr["type"].ToString() == "自动未执行")
            {
                CommonHelper.WriteTaskLog(dr["ScheduledTaskId"].ToString(), "2", "", "1");//开始执行
            }
            DataTable dtCreateEmp = CommonHelper.GetCreateEmp(dr["factoryid"].ToString());//获取开卡人
            if (dtCreateEmp.Rows.Count == 0)
            {
                LogHelp.WriteLog(string.Format("分厂：热表，任务：{0} 执行完毕，分厂未配置开卡人", dr["taskname"].ToString()));
                CommonHelper.WriteTaskLog(dr["ScheduledTaskId"].ToString(), "4", " 任务执行完毕，分厂未配置开卡人", "1");
                return;
            }
            Dictionary<string, string> dicAttr = CommonHelper.GetTaskAttr(dr["ScheduledTaskId"].ToString());//获取定时任务的属性
            //if (dicAttr["接收参考"] == "转工计划开始时间")
            //{

            //}
            int coverCycle = int.Parse(dicAttr["覆盖周期"]);
            /*获取热表待接收的排产转工数据*/
            uMESProcessResult result = apsPlanConfirmBusiness.GetApsPlanShipReceivedDatas(new Dictionary<string, string> { 
                                        { "FactoryID", dr["factoryid"].ToString() }, 
                                        { "Status", "2" }, 
                                        { "isPage", "false" },
                                        { "PlanStartDate", DateTime.Now.ToString("yyyy-MM-dd") + " 00:00:00" },
                                        { "PlanEndDate", DateTime.Now.AddDays(coverCycle).ToString("yyyy-MM-dd") + " 23:59:59"}});
            if (!result.Result)
            {
                LogHelp.WriteLog(string.Format("分厂：热表，任务：{0} 查询待接收的排产转工数据报错，原因：{1}", dr["taskname"].ToString(), result.Message));
                CommonHelper.WriteTaskLog(dr["ScheduledTaskId"].ToString(), "4", " 任务执行完毕，查询待接收的排产转工数据报错，原因：" + result.Message, "1");
                return;
            }
            /*定义参数*/
            int scount = 0, ecount = 0;//成功条数，失败条数
            string msg = string.Empty;//提示消息
            CurrentUserInfo user = new CurrentUserInfo()
            {
                APIUserName = serverAPIUserName,
                APIPassword = serverAPIPassword,
                Factory = dr["factoryname"].ToString(),
                FactoryID = dr["factoryid"].ToString(),
                EmployeeID = dtCreateEmp.Rows[0]["employeeid"].ToString(),
                EmployeeName = dtCreateEmp.Rows[0]["employeename"].ToString()
            };//固定开卡人
            DataTable dtApsShip = result.DBTable;
            LogHelp.WriteLog(string.Format("分厂：热表，任务：{0}开始执行，执行转工计划接收总数：{1}-------------------------------------------------------------", dr["taskname"].ToString(), dtApsShip.Rows.Count));
            CommonHelper.UpdateTaskLogStartDate(dr["ScheduledTaskId"].ToString()); //更新定时任务日志的开始时间为当前时间
            /*开始循环执行数据*/
            for (int i = 0; i < dtApsShip.Rows.Count; i++)
            {
                //检查是否提前终止
                if (DatabaseHelper.GetSingle(string.Format(@"select 1 from ScheduledTaskLogs sl
                            where sl.scheduledtaskid='{0}' and sl.islatest=1 and sl.taskexeendtime is not null", dr["ScheduledTaskId"].ToString())) != null)
                {
                    break;
                }
                DataRow drApsShip = dtApsShip.Rows[i];
                string sql = string.Format("SELECT apd.shiprecplanstartdate,apd.shiprecplanenddate,nvl(apd.status,'0') status FROM apsplandetail apd WHERE apd.apsplandetailid = '{0}'", drApsShip["apsplandetailid"].ToString());
                DataTable dtAps = DatabaseHelper.Query_ReturnDatTable(sql);
                if (dtAps.Rows.Count == 0)
                {
                    ecount++;
                    LogHelp.WriteLog(string.Format("分厂：热表，任务：{0} 的第{1}个批次：{2}的转工工序：{3}，没有排产数据", dr["taskname"].ToString(), (i + 1).ToString(), drApsShip["containername"].ToString(), drApsShip["workflowstepname"].ToString()));
                    continue;
                }
                if (!string.IsNullOrWhiteSpace(dtAps.Rows[0]["shiprecplanstartdate"].ToString()) || !string.IsNullOrWhiteSpace(dtAps.Rows[0]["shiprecplanenddate"].ToString()))
                {
                    ecount++;
                    LogHelp.WriteLog(string.Format("分厂：热表，任务：{0} 的第{1}个批次：{2}的转工工序：{3}，存在反馈日期，需主制分厂确认", dr["taskname"].ToString(), (i + 1).ToString(), drApsShip["containername"].ToString(), drApsShip["workflowstepname"].ToString()));
                    continue;
                }
                /*执行转工接收*/
                if (DatabaseHelper.ExecuteSql(string.Format("UPDATE apsplandetail apd SET apd.shipreceiveempid = '{0}', apd.shipreceivedate = to_date('{1}','yyyy/mm/dd'),apd.lastchangedate = to_date('{2}','yyyy/mm/dd hh24:mi:ss'), apd.status = '3' WHERE apd.apsplandetailid = '{3}'", dtCreateEmp.Rows[0]["employeeid"].ToString(), DateTime.Now.ToShortDateString(), DateTime.Now.ToString(), drApsShip["apsplandetailid"].ToString())) > 0)
                {
                    msg = "转工排产接收成功";
                    scount++;
                    /*转工接收自动开卡*/
                    if (dicAttr["接收后自动开卡"] == "是")
                    {
                        result = rbBusiness.SaveApsShipStartContainer(string.Format("'{0}'", drApsShip["apsplandetailid"].ToString()), user);
                        msg += result.Result ? "，开卡成功！" : "，开卡失败！";
                    }
                }
                else
                {
                    msg = "转工排产接收失败";
                    ecount++;
                }
                LogHelp.WriteLog(string.Format("分厂：热表，任务：{0} 的第{1}个批次：{2}的转工序：{3}，{4}", dr["taskname"].ToString(), (i + 1).ToString(), drApsShip["containername"].ToString(), drApsShip["workflowstepname"].ToString(), msg));
            }
            //此任务执行完毕
            CommonHelper.WriteTaskLog(dr["ScheduledTaskId"].ToString(), "4", string.Format(" 任务执行完毕，执行批次转工序计划接收数：{0}，成功：{1}，失败：{2}", scount + ecount, scount, ecount), "1");
            LogHelp.WriteLog(string.Format("分厂：热表，任务：{0} 执行完毕----------------------------------------------------------------------", dr["taskname"].ToString()));
            //更新任务下次执行时间
            DatabaseHelper.ExecuteSql(string.Format(@"update ScheduledTask set Nextexcutime = to_date(to_char(Nextexcutime,'yyyy-mm-dd') || ' ' || to_char(taskstarttime,'hh24:mi:ss'),'yyyy-mm-dd hh24:mi:ss') where ScheduledTaskid='{0}'", dr["ScheduledTaskId"].ToString()));
        }

        /// <summary>
        /// 获取开卡人
        /// </summary>
        /// <param name="factoryID"></param>
        /// <returns></returns>
        private DataTable GetCreateEmp(string factoryID)
        {
            Dictionary<string, string> dic = new Dictionary<string, string>();
            string sql = string.Format(@"SELECT e.employeeid,e.employeename FROM userattribute u 
                                        INNER JOIN employee e ON e.employeename = u.attributevalue
                                        WHERE u.parentid = '{0}' AND u.userattributename = '开卡人'", factoryID);
            return DatabaseHelper.Query_ReturnDatTable(sql);
        }

    }
}
